/*
 * =====================================================================================
 *
 *       Filename:  cl_singleton.hxx
 *
 *    Description:  a singleton pattern impl
 *
 *        Version:  1.0
 *        Created:  02/28/2010 06:04:38 PM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Ken Chen (Ziliang), zlchen.ken@gmail.com
 *        Company:  EMC
 *
 * =====================================================================================
 */

#ifndef _CL_SINGLETON_HXX_
#define _CL_SINGLETON_HXX_

#include <memory>
#include "cl_mutex.hxx"
#include "cl_lock_guard.hxx"

namespace neo
{
// A little over-engineering :) 
template<typename T>
class CLSingleton
{
public:
	static inline T* instance(void)
	{
		return m_pInstance.get();
	}

	static inline T* create(void)
	{
    // Double checked and lock pattern (DCLP) 
		if(m_pInstance.get() == NULL)
		{
      CLLockGuard guard(*m_pMutex.get());
      if(m_pInstance.get() == NULL)
      {
			  m_pInstance.reset(new T);
      }
		}

		return m_pInstance.get();
	}

private:
	static std::shared_ptr<T> m_pInstance;
  static std::shared_ptr<CLLock> m_pMutex;
};

template<typename T> std::shared_ptr<T> CLSingleton<T>::m_pInstance;
template<typename T> std::shared_ptr<CLLock> CLSingleton<T>::m_pMutex(new CLMutex);

} // neo

#endif //_CL_SINGLETON_HXX_

